//
// Created by macbookpro on 2024/4/12.
//


#ifndef TESTDESIGNPATTERNSSTRATEGY_DUCK_H
#define TESTDESIGNPATTERNSSTRATEGY_DUCK_H

#include <memory>
#include "FlyBehavior.h"
#include "QuackBehavior.h"
#include <iostream>

class Duck {
protected:
    //智能指针unique_ptr：独占对象，不允许复制；动态管理分配对象的生命周期
    std::unique_ptr<FlyBehavior> _flyBehavior;
    std::unique_ptr<QuackBehavior> _quackBehavior;
public:
    //explicit表示该构造函数只能显式调用，禁止隐式转换。
    /*
     * 移动语义：不复制对象，而只是让新的对象名指向原对象名所指对象，并且将原对象所指的置空。
     * 完美转发：可以撰写接受任意参数的函数模版，并将其转发到其他函数，目标函数会接受与其转发函数所接受的完全相同的参数。
     * &&（右值引用）：结合了移动语义和完美转发；可以绑定到临时对象。
     * std::move（把实参强制转换为右值）:无条件地右值类型的强制类型转换；
     * std:;forward：仅对绑定到右值的引用实施向右值类型的强制转换。
     * 针对右值引用实施std::move，万能引用实施std::forward
    */
    explicit Duck(std::unique_ptr<FlyBehavior> &&flyBehavior ={},
                  std::unique_ptr<QuackBehavior> &&quackBehavior={})
                  :_flyBehavior(std::move(flyBehavior))
                  ,_quackBehavior(std::move(quackBehavior)){

    }
    //上下文允许在运行时替换策略对象。
    void setFlyBehavior(std::unique_ptr<FlyBehavior>&&flyBehavior){
        _flyBehavior = std::move(flyBehavior);
    }

    void setQuackBehavior(std::unique_ptr<QuackBehavior>&&quackBehavior){
        _quackBehavior = std::move(quackBehavior);
    }
    //执行飞
    void performFly() const{
        _flyBehavior->fly();
    }
    //执行叫
    void performQuack() const{
        _quackBehavior->quack();
    }
    void swim() const{
        std::cout<<"All ducks float, even decoys"<<std::endl;
    }

    virtual void display() const = 0;

};


#endif //TESTDESIGNPATTERNSSTRATEGY_DUCK_H
